package org.opens.javaskill.thread.api;

import java.util.stream.Stream;

/**
 * @Date 2020/8/14 23:07
 * @Created by 99126
 */
public class SleepAndWaitDifferent {

    private final static Object LOCK = new Object();
    private final static Object LOCK1 = new Object();

    public static void main(String[] args) {
        //new Thread(() -> {
        //    m1();
        //}, "t1").start();
        new Thread(() -> {
            synchronized (LOCK1) {
                m1();
            }
        }, "t2").start();
    }

    public static void m1() {
        try {
            LOCK.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

class SleepAndWaitDifferent1 {

    /**
     * 功能:
     *      验证多线程情况下未抢到锁的线程在锁释放之后会立即执行还是必须执行notify唤醒.
     * 输出:
     * ```
     * s1 start
     * s1 end
     * s3 start
     * s3 end
     * s2 start
     * s2 end
     * ```
     * 说明:
     *      1. 可以发现, 未抢到锁的线程相当于处于sleep状态, 锁释放之后会接着执行.
     */
    public static void main(String[] args) {
        Object lock = new Object();
        Stream.of("s1", "s2", "s3").forEach(x -> {
            new Thread(() -> {
                synchronized (lock) {
                    System.out.println(Thread.currentThread().getName() + " start");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + " end");
                }
            }, x).start();
        });
    }

}

class SleepAndWaitDifferent2 {

    /**
     * 说明:
     *      1. 当thread1线程启动之后, 如果执行wait方法时设置了超时时间, 则如果超时后未被执行, 则恢复执行, 如果在此wait期间执行了interrupt
     *      打断操作, 休眠的线程是会被打断的.
     */
    public static void main(String[] args) throws InterruptedException {
        Object lock = new Object();
        Thread thread1 = new Thread(() -> {
            synchronized (lock) {
                System.out.println(Thread.currentThread().getName() + " start");
                try {
                    lock.wait(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " end");
            }
        }, "thread1");
        thread1.start();
        Thread.sleep(2000);
        thread1.interrupt();
    }

}

